package cn.tools.jwt.client.utils;


import cn.hutool.core.io.FileUtil;
import cn.tools.core.exception.BizException;
import cn.tools.jwt.client.entiry.JwtHeadConfig;
import cn.tools.jwt.client.service.JwtCreateTokenService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Map;

/**
 * @author: e
 * @date: 2021/12/9
 * @description:
 */

@Slf4j
public class JwtCreateToken implements JwtCreateTokenService {
    private JwtHeadConfig jwtHeadConfig;

    public JwtCreateToken(JwtHeadConfig jwtHeadConfig){
        this.jwtHeadConfig = jwtHeadConfig;
    }


    @Override
    public String createJwt(Map<String,Object> userInfo) throws Exception {
        if(jwtHeadConfig.getHead().get("alg") != null && jwtHeadConfig.getHead().get("alg").equals("HS256")){
            return createHS256(userInfo);
        }
        else if(jwtHeadConfig.getHead().get("alg") != null && jwtHeadConfig.getHead().get("alg").equals("RS256")) {
            return createRS256(userInfo);
        }
        throw new BizException("没有配置jwt配置");
    }



    //创建RS256jwt
    private String createRS256(Map<String,Object> userInfo) throws Exception {
        String jwt = Jwts.builder()
                .setHeader(jwtHeadConfig.getHead())
                .setClaims(userInfo)
                .signWith(SignatureAlgorithm.RS256,getPriKey())
                .compact();

        return jwt;
    }



    //获取私钥
    public PrivateKey getPriKey(){
        PrivateKey privateKey;
        try {
            File file = new File(jwtHeadConfig.getPrikey());
            InputStream resourceAsStream = new FileInputStream(file);
            DataInputStream dis = new DataInputStream(resourceAsStream);
            byte[] keyBytes = new byte[resourceAsStream.available()];
            dis.readFully(keyBytes);
            PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory kf = KeyFactory.getInstance("RSA");
            privateKey = kf.generatePrivate(spec);
        }catch (Exception e) {
            throw new BizException("获取秘钥失败");
        }
        return privateKey;
    }



    //创建hs256jwt
    private String createHS256(Map<String,Object> userInfo){
        String jwt = Jwts.builder()
                .setHeader(jwtHeadConfig.getHead())
                .setClaims(userInfo)
                .setId("jwt001")
                .signWith(SignatureAlgorithm.HS256,jwtHeadConfig.getKey())
                .compact();
        return jwt;
    }






    //生成公钥和私钥
    public void createKeyFile() throws NoSuchAlgorithmException {
        String key = jwtHeadConfig.getKey();

        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");
        SecureRandom secureRandom = new SecureRandom(key.getBytes());
        keyPairGenerator.initialize(1024, secureRandom);
        KeyPair keyPair = keyPairGenerator.genKeyPair();

        byte[] publicKeyBytes = keyPair.getPublic().getEncoded();
        byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();

        if(jwtHeadConfig.getPrikey() == null || jwtHeadConfig.getPrikey().equals("")){
            throw new NoSuchAlgorithmException("没有配置公钥或私钥路径信息");
        }

        FileUtil.writeBytes(publicKeyBytes, jwtHeadConfig.getPubkey());
        FileUtil.writeBytes(privateKeyBytes, jwtHeadConfig.getPrikey());
    }
}
